﻿
    using System;
    using System.IO;
namespace YoucaiReader.Helper.Drawing
{
    public class ByteDataInputStream
    {
        private readonly sbyte[] byteBuffer;
        private bool isBigEndian;
        private int p;

        public ByteDataInputStream(sbyte[] inBuffer, bool isBigEndian_0)
        {
            this.byteBuffer = inBuffer;
            this.isBigEndian = isBigEndian_0;
        }

        public int getAvailableLength()
        {
            return (this.byteBuffer.Length - this.p);
        }

        public sbyte getByte(int index)
        {
            return this.byteBuffer[index];
        }

        public sbyte[] getData()
        {
            return this.byteBuffer;
        }

        public int getPosition()
        {
            return this.p;
        }

        public bool readBoolean()
        {
            return (this.byteBuffer[this.p++] != 0);
        }

        public sbyte readByte()
        {
            if ((this.p + 1) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before reading one sbyte");
            }
            return this.byteBuffer[this.p++];
        }

        public sbyte[] readBytes(int length)
        {
            if (length < 0)
            {
                length = this.byteBuffer.Length - this.p;
            }
            sbyte[] dst = new sbyte[length];
            Buffer.BlockCopy(this.byteBuffer, this.p, dst, 0, length);
            this.p += length;
            return dst;
        }

        public string readFromEncoding(int index, int size, int encoding)
        {
            return UnicodeUtils.stringFromEncoding(this.byteBuffer, index, size, encoding);
        }

        public int readInt()
        {
            if ((this.p + 4) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before reading 4 bytes");
            }
            if (this.isBigEndian)
            {
                return ((((this.byteBuffer[this.p++] << 0x18) + ((this.byteBuffer[this.p++] & 0xff) << 0x10)) + ((this.byteBuffer[this.p++] & 0xff) << 8)) + (this.byteBuffer[this.p++] & 0xff));
            }
            return ((((this.byteBuffer[this.p++] & 0xff) + ((this.byteBuffer[this.p++] & 0xff) << 8)) + ((this.byteBuffer[this.p++] & 0xff) << 0x10)) + (this.byteBuffer[this.p++] << 0x18));
        }

        public static int readInt(sbyte[] src, int index, bool bigEndian)
        {
            if ((index + 4) > src.Length)
            {
                return -1;
            }
            if (bigEndian)
            {
                return ((((src[index++] << 0x18) + ((src[index++] & 0xff) << 0x10)) + ((src[index++] & 0xff) << 8)) + (src[index++] & 0xff));
            }
            return ((((src[index++] & 0xff) + ((src[index++] & 0xff) << 8)) + ((src[index++] & 0xff) << 0x10)) + (src[index++] << 0x18));
        }

        public long readLong()
        {
            if ((this.p + 8) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before reading 8 bytes");
            }
            if (this.isBigEndian)
            {
                return (long) ((((((((this.byteBuffer[this.p++] << 0x18) + ((this.byteBuffer[this.p++] & 0xff) << 0x10)) + ((this.byteBuffer[this.p++] & 0xff) << 8)) + (this.byteBuffer[this.p++] & 0xff)) + ((this.byteBuffer[this.p++] & 0xff) << 0x18)) + ((this.byteBuffer[this.p++] & 0xff) << 0x10)) + ((this.byteBuffer[this.p++] & 0xff) << 8)) + (this.byteBuffer[this.p++] & 0xff));
            }
            return (long) ((((((((this.byteBuffer[this.p++] & 0xff) + ((this.byteBuffer[this.p++] & 0xff) << 8)) + ((this.byteBuffer[this.p++] & 0xff) << 0x10)) + ((this.byteBuffer[this.p++] & 0xff) << 0x18)) + (this.byteBuffer[this.p++] & 0xff)) + ((this.byteBuffer[this.p++] & 0xff) << 8)) + ((this.byteBuffer[this.p++] & 0xff) << 0x10)) + (this.byteBuffer[this.p++] << 0x18));
        }

        public short readShort()
        {
            if ((this.p + 2) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before reading two bytes");
            }
            if (this.isBigEndian)
            {
                return (short) ((this.byteBuffer[this.p++] << 8) + (this.byteBuffer[this.p++] & 0xff));
            }
            return (short) ((this.byteBuffer[this.p++] & 0xff) + (this.byteBuffer[this.p++] << 8));
        }

        public static int readShort(sbyte[] data, int offset)
        {
            return ((data[offset] & 0xff) + (data[offset + 1] << 8));
        }

        public int readStopEncodedInt()
        {
            int num = 0;
            int num2 = 8;
            byte num3 = (byte) this.readByte();
            int num4 = 0;
            while (num4 < num2)
            {
                if ((num3 & 0x80) == 0)
                {
                    num = (num << 7) | num3;
                    num3 = (byte) this.readByte();
                    num4++;
                }
                else
                {
                    num = (num << 7) | (num3 & 0x7f);
                    num4++;
                    return num;
                }
            }
            return num;
        }

        public string readString(int maxSize)
        {
            if ((this.p + maxSize) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before reading " + maxSize + " bytes");
            }
            this.p += maxSize;
            return readString(this.byteBuffer, this.p - maxSize, maxSize);
        }

        public static string readString(sbyte[] data, int offset, int maxSize)
        {
            if (maxSize < 0)
            {
                maxSize = data.Length;
            }
            int index = offset;
            while ((data[index] != 0) && (index < (offset + maxSize)))
            {
                index++;
            }
            try
            {
                return UnicodeUtils.stringFromEncoding(data, offset, index, 0x4e4);
            }
            catch (Exception)
            {
                return EncodingConversion.bytesToString(data, offset, index);
            }
        }

        public string readStringUTF16BE(int size)
        {
            string str = this.readStringUTF16BE(this.p, size);
            this.p += size;
            return str;
        }

        public string readStringUTF16BE(int offset, int size)
        {
            return UnicodeUtils.stringFromEncoding(this.byteBuffer, offset, size, 0xfdea);
        }

        public string readUTF8String(int index, int size)
        {
            return UnicodeUtils.stringFromEncoding(this.byteBuffer, index, size, 0xfde9);
        }

        public void readVoid(int size)
        {
            this.p += size;
        }

        public string readWesternString(int index, int size)
        {
            return UnicodeUtils.stringFromEncoding(this.byteBuffer, index, size, 0x4e4);
        }

        public void setPosition(int pos)
        {
            this.p = pos;
        }

        public void writeBoolean(bool value_ren)
        {
            if (value_ren)
            {
                this.byteBuffer[this.p] = 1;
            }
            else
            {
                this.byteBuffer[this.p] = 0;
            }
            this.p++;
        }

        public void writeBytes(sbyte[] bytes)
        {
            if ((this.p + bytes.Length) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before writing " + bytes.Length + " bytes");
            }
            Buffer.BlockCopy(bytes, 0, this.byteBuffer, this.p, bytes.Length);
            this.p += bytes.Length;
        }

        public void writeInt(int value)
        {
            if ((this.p + 4) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before writing 4 bytes");
            }
            if (this.isBigEndian)
            {
                this.byteBuffer[this.p++] = (sbyte) (value >> 0x18);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x10) & 0xff);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 8) & 0xff);
                this.byteBuffer[this.p++] = (sbyte) (value & 0xff);
            }
            else
            {
                this.byteBuffer[this.p++] = (sbyte) (value & 0xff);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 8) & 0xff);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x10) & 0xff);
                this.byteBuffer[this.p++] = (sbyte) (value >> 0x18);
            }
        }

        public static void writeInt(sbyte[] src, int index, bool bigEndian, int value_ren)
        {
            if ((index + 4) <= src.Length)
            {
                if (bigEndian)
                {
                    src[index++] = (sbyte) (value_ren >> 0x18);
                    src[index++] = (sbyte) ((value_ren >> 0x10) & 0xff);
                    src[index++] = (sbyte) ((value_ren >> 8) & 0xff);
                    src[index++] = (sbyte) (value_ren & 0xff);
                }
                else
                {
                    src[index++] = (sbyte) (value_ren & 0xff);
                    src[index++] = (sbyte) ((value_ren >> 8) & 0xff);
                    src[index++] = (sbyte) ((value_ren >> 0x10) & 0xff);
                    src[index++] = (sbyte) (value_ren >> 0x18);
                }
            }
        }

        public void writeLong(long value)
        {
            if ((this.p + 8) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before writing 8 bytes");
            }
            if (this.isBigEndian)
            {
                this.byteBuffer[this.p++] = (sbyte) (value >> 0x38);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x30) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 40) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x20) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x18) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x10) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 8) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) (value & 0xffL);
            }
            else
            {
                this.byteBuffer[this.p++] = (sbyte) (value & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 8) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x10) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x18) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x20) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 40) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) ((value >> 0x30) & 0xffL);
                this.byteBuffer[this.p++] = (sbyte) (value >> 0x38);
            }
        }

        public void writeShort(short value)
        {
            if ((this.p + 2) > this.byteBuffer.Length)
            {
                throw new EndOfStreamException("this input stream reaches the end before writing 2 bytes");
            }
            if (this.isBigEndian)
            {
                this.byteBuffer[this.p++] = (sbyte) ((((ushort) value) >> 8) & 0xff);
                this.byteBuffer[this.p++] = (sbyte) (value & 0xff);
            }
            else
            {
                this.byteBuffer[this.p++] = (sbyte) (value & 0xff);
                this.byteBuffer[this.p++] = (sbyte) ((((ushort) value) >> 8) & 0xff);
            }
        }
    }
}

